﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Agile.Engine.View;
using System.Collections;
using Agile.Engine;
using Agile.Engine.Data;
using System.Data;
using Agile.Engine.Utils;
using Fis.Win.Utils;

namespace Fis.Win.Rules
{
    public class AccountTreatViewProvider : ClientViewProvider
    {
        public string Master { get; set; }
        public string Detail { get; set; }
        public string Book { get; set; }
        public string Rest { get; set; }
        //GlobleViewProvider Globle = AppSession.GetViewProvider("GlobleViewProvider") as GlobleViewProvider;

        public override Hashtable InitializeViewModel(Hashtable args)
        {
            var FormName = args["FormName"].ToString();
            var Sql = (string)null;
            var filter0 = (string)null;
            int Year = 0;
            var Range = 0;
            var StarTime = System.DateTime.Now;
            var EndTime = System.DateTime.Now;
            switch (FormName)
            {
                #region //反初始化
                case "反初始化":
                    args["InitializeRange"] = DateTime.Parse(AppSession.Book["FBOOKSTARTIME"].ToString()).Month;
                    args["Range"] = AppSession.Book["FBOOKRANGE"];
                    break;
                #endregion
                #region //凭证审核
                case "凭证审核":
                    Sql = (string)null;
                    Year = DateTime.Parse(AppSession.Book["FBOOKSTARTIME"].ToString()).Year;
                    Range = int.Parse(AppSession.Range);
                    Range = (Range < 1) ? 1 : (Range > 12) ? 12 : Range;
                    args["Year"] = Year;
                    args["Range"] = Range;
                    StarTime = DateTime.Parse(string.Format("{0}-{1}-1 00:00:00", Year, Range));
                    EndTime = DateTime.Parse(string.Format("{0}-{1}-1 00:00:00", Year, Range)).AddMonths(1).AddMilliseconds(-1);
                    Sql = string.Format("select * from TBILLMASTER where FENTERDATE>='{0}' and FENTERDATE<'{1}'", StarTime, EndTime);
                    args["BillMasterTB"] = DataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, DataTableName, Sql);
                    filter0 = string.Format("and FENTERDATE>='{0}' and FENTERDATE<'{1}'", StarTime, EndTime);
                    Sql = ObjectContext.GetResource("SqlResource").Format("billQuery", filter0
                            , string.IsNullOrEmpty(null) ? string.Empty : ObjectContext.GetResource("SqlResource").Format("billSubQuery", null));
                    args["BillDetailTB"] = DataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, DataTableName, Sql);
                    args["filter0"] = filter0; args["filter1"] = "";
                    args["FCHECKED"] = AppSession.UserSID;
                    break;
                #endregion
                #region //结账
                case "结账":
                    args["Year"] = DateTime.Parse(AppSession.Book["FBOOKSTARTIME"].ToString()).Year;
                    Range = int.Parse(AppSession.Range);
                    Range = (Range < 1) ? 1 : (Range > 12) ? 12 : Range;
                    args["Range"] = Range;
                    break;
                #endregion
                #region //反结账
                case "反结账":
                    args["Year"] = DateTime.Parse(AppSession.Book["FBOOKSTARTIME"].ToString()).Year;
                    Range = int.Parse(AppSession.Range);
                    Range = (Range < 1) ? 1 : (Range > 12) ? 12 : Range;
                    args["Range"] = Range;
                    args["BookStarTime"] = AppSession.Book["FBOOKSTARTIME"].ToString();
                    break;
                #endregion
                default:
                    break;
            }
            return args;
        }

        public override Hashtable ExecuteQuery(object param)
        {
            Hashtable mode = param as Hashtable;
            var Action = mode["Action"].ToString();
            var globle = AppSession.GetViewProvider("GlobleViewProvider") as GlobleViewProvider;
            switch (Action)
            {
                case "初始凭证检测":
                    ///同步凭证
                    if (globle.HasInitBillNoSync())
                    {
                        mode["State"] = -1;
                        break;
                    }
                    globle.BillSyncByRange(0);
                    mode = InitializeBillCheck(mode);
                    break;
                case "初始科目余额表生成":
                    mode = InitializeRestBuild(mode);
                    break;
                case "结转损益":
                    ///同步凭证
                    if (globle.HasBillNoSync())
                    {
                        mode["State"] = -1;
                        break;
                    }
                    mode = TransferProfit(mode);
                    break;
                case "期末调汇":
                    ///同步凭证
                    if (globle.HasBillNoSync())
                    {
                        mode["State"] = -1;
                        break;
                    }
                    mode = AdjustRate(mode);
                    break;
                case "凭证审核":
                    ///同步凭证
                    if (globle.HasBillNoSync())
                    {
                        mode["State"] = -1;
                        break;
                    }
                    mode = CertificateAuditBillCheck(mode);
                    break;
                case "凭证过账":
                    ///同步凭证
                    if (globle.HasBillNoSync())
                    {
                        mode["State"] = -1;
                        break;
                    }
                    mode = CertificatePosting(mode);
                    break;
                case "凭证反过账":
                    mode = ReverseCertificatePosting(mode);
                    break;
                case "结账检测":
                    ///同步凭证
                    if (globle.HasBillNoSync())
                    {
                        mode["State"] = -1;
                        break;
                    }
                    globle.BillSyncByRange(int.Parse(AppSession.Range));
                    mode = AccountSettleCheck(mode);
                    break;
                case "科目余额表生成":
                    mode = AccountSettleRestBuild(mode);
                    break;
            }
            return mode;
        }

        public override bool ExecuteUpdate(Hashtable viewModel)
        {
            var Action = viewModel["Action"].ToString();
            bool Return = false;
            switch (Action)
            {
                case "初始化提交":
                    Return = InitializeSubmit(viewModel);
                    break;
                case "反初始化提交":
                    Return = ReverseInitializeSubmit(viewModel);
                    break;
                case "结转损益提交":
                    Return = TransferProfitSubmit(viewModel);
                    break;
                case "期末调汇提交":
                    Return = AdjustRateSubmit(viewModel);
                    break;
                case "凭证审核提交":
                    Return = CertificateAuditSubmit(viewModel);
                    break;
                case "凭证反审核提交":
                    Return = ReverseCertificateAuditSubmit(viewModel);
                    break;
                case "凭证过账提交":
                    Return = CertificatePostingSubmit(viewModel);
                    break;
                case "凭证反过账提交":
                    Return = ReverseCertificatePostingSubmit(viewModel);
                    break;
                case "结账信息提交":
                    Return = AccountSettleSubmit(viewModel);
                    break;
                case "反结账信息提交":
                    Return = ReverseAccountSettleSubmit(viewModel);
                    break;
                case "同步凭证号":
                    Return = SyncBillNO(viewModel);
                    break;
                default:
                    Return = false;
                    break;
            }
            return Return;
        }

        #region //共通

        public Hashtable BillCheck(Hashtable args)
        {
            System.Collections.Hashtable mode = new System.Collections.Hashtable();
            var BillDetailTB = args["BillDetailTB"] as DataTable;
            var BillMasterTB = args["BillMasterTB"] as DataTable;
            mode["BillMasterCount"] = BillMasterTB.Rows.Count.ToString();
            var ErrorBillID = (string)null;
            var TempErrorBillID = (string)null;
            if (BillDetailTB.Rows.Count == 0)
            {
                mode["State"] = 0;
                return mode;
            }
            else
            {
                for (int i = 0; i < BillDetailTB.Rows.Count; i++)
                {
                    args["LineNum"] = i.ToString();
                    TempErrorBillID = BillDetailCheck(args);
                    if (!StringUtils.IsEmpty(TempErrorBillID))
                    {
                        if (StringUtils.IsEmpty(ErrorBillID))
                        {
                            ErrorBillID = string.Format("'{0}'", TempErrorBillID);
                        }
                        else
                        {
                            ErrorBillID += string.Format(",'{0}'", TempErrorBillID);
                        }
                    }
                }
                ///验证借贷方金额是否一致
                foreach (var m in BillMasterTB.AsEnumerable())
                {
                    object result = 0;
                    if (BillDetailTB.Columns.Contains("FVCHID"))
                        result = BillDetailTB.Compute("sum(FDEBITAMOUNT)-sum(FCREDITAMOUNT)", string.Format("FVCHID='{0}' ", m["SID"]));
                    else if (BillDetailTB.Columns.Contains("FNO"))
                        result = BillDetailTB.Compute("sum(FDEBITAMOUNT)-sum(FCREDITAMOUNT)", string.Format("SID='{0}' AND FNO={1} ", m["SID"], m["FNO"]));

                    if (ReportUtils.NullParse(result) != 0)
                    {
                        //不一致
                        if (StringUtils.IsEmpty(ErrorBillID))
                        {
                            ErrorBillID = string.Format("'{0}'", m["SID"]);
                        }
                        else
                        {
                            ErrorBillID += string.Format(",'{0}'", m["SID"]);
                        }
                    }
                }
                if (!StringUtils.IsEmpty(ErrorBillID))
                {
                    var ErrorBillMasterTB = DataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, "ErrorBillMasterCount", string.Format("select SID from TBILLMASTER where SID in ({0})", ErrorBillID));
                    mode["ErrorBillMasterCount"] = ErrorBillMasterTB.Rows.Count.ToString();
                    mode["ErrorBillMasterID"] = string.Join("','", (from b in ErrorBillMasterTB.Select() select b["SID"].ToString()).ToArray());
                    mode["ErrorBillDetailID"] = ErrorBillID;
                    mode["State"] = 1;
                    return mode;
                }
                mode["State"] = 0;
                return mode;
            }
        }

        string BillDetailCheck(Hashtable args)
        {
            var BillDetailTB = args["BillDetailTB"] as DataTable;
            var AccountTB = DataContext.DefaultModel.QueryTable("TACCOUNT");
            int i = int.Parse(args["LineNum"].ToString());
            var SID = BillDetailTB.Rows[i]["SID"].ToString();
            var AccountCode = BillDetailTB.Rows[i]["FACCOUNTCODE"].ToString();
            //凭证科目数据为空
            if (StringUtils.IsEmpty(AccountCode))
                return SID;
            //科目是否存在
            //var AccountTBRows = AccountTB.Select(string.Format("SID='{0}'", AccountCode));
            //if (AccountTBRows.Length == 0)
            //    return SID;
            //是否为最子集科目
            var LowerAccountTB = CacheContext.LowerAccountCache();
            var AccountTBRows = LowerAccountTB.Select(string.Format("SID='{0}'", AccountCode));
            if (AccountTBRows.Length <= 0)
                return SID;
            //摘要是否为空
            if (StringUtils.IsEmpty(BillDetailTB.Rows[i]["FEXPLANATION"].ToString()))
                return SID;
            //借贷金额是否都为空
            if (StringUtils.IsEmpty(BillDetailTB.Rows[i]["FDEBITAMOUNT"].ToString()) &&
                StringUtils.IsEmpty(BillDetailTB.Rows[i]["FCREDITAMOUNT"].ToString()))
                return SID;
            //科目有辅助核算
            if (AccountTBRows[0]["FISFZHS"].ToString() == "1")
            {
                //有外币核算
                if (AccountTBRows[0]["FWBHS"].ToString() != "0")
                {
                    //外币借贷金额都为空
                    if (StringUtils.IsEmpty(BillDetailTB.Rows[i]["FCURRENCYDEBIT"].ToString()) &&
                    StringUtils.IsEmpty(BillDetailTB.Rows[i]["FCURRENCYCREDIT"].ToString()))
                        return SID;
                    //汇率为空
                    if (StringUtils.IsEmpty(BillDetailTB.Rows[i]["FRATE"].ToString()))
                        return SID;
                }
                //有数量核算
                if (AccountTBRows[0]["FQUANTITY"].ToString() != "0")
                {
                    //借贷数量都为空
                    if (StringUtils.IsEmpty(BillDetailTB.Rows[i]["FQUANTITYDEBIT"].ToString()) &&
                        StringUtils.IsEmpty(BillDetailTB.Rows[i]["FQUANTITYCREDIT"].ToString()))
                        return SID;
                    //单价为空
                    if (StringUtils.IsEmpty(BillDetailTB.Rows[i]["FUNITPRICE"].ToString()))
                        return SID;
                }
                //有其他辅助核算项
                if (!StringUtils.IsEmpty(AccountTBRows[0]["FFZHS"].ToString()))
                {
                    //辅助核算信息为空
                    if (StringUtils.IsEmpty(BillDetailTB.Rows[i]["FHSVALUE"].ToString()))
                        return SID;
                }
            }
            //检测正常
            return null;
        }

        DataTable RateBuild(Hashtable args)
        {
            var AccountTB = args["AccountTB"] as DataTable;
            var RestTB = args["RestTB"] as DataTable;
            var TempBillTB = args["TempBillTB"] as DataTable;
            var Range = args["Range"].ToString();
            var SID = (string)null;
            var FCode = (string)null;
            for (int i = 0; i < AccountTB.Rows.Count; i = i + 1)
            {
                var RestRow = RestTB.NewRow();
                SID = AccountTB.Rows[i]["SID"].ToString();
                FCode = AccountTB.Rows[i]["FCODE"].ToString();
                FCode = string.Format("'{0}'", string.Join("','",
                        (from a in AccountTB.Select(string.Format("FCODE like '{0}%'", FCode)) select a["SID"].ToString()).ToArray()));
                RestRow["SID"] = "";
                RestRow["FACCCODE"] = SID;
                //初始化起初余额
                RestRow["FDEBITAMOUNTQC"] = decimal.Parse("0.000000");
                RestRow["FCREDITAMOUNTQC"] = decimal.Parse("0.000000");
                RestRow["FCURRENCYDEBITQC"] = decimal.Parse("0.000000");
                RestRow["FCURRENCYCREDITQC"] = decimal.Parse("0.000000");
                RestRow["FQUANTITYDEBITQC"] = decimal.Parse("0.000000");
                RestRow["FQUANTITYCREDITQC"] = decimal.Parse("0.000000");
                //初始化本期余额
                RestRow["FDEBITAMOUNTBQ"] = decimal.Parse("0.000000");
                RestRow["FCREDITAMOUNTBQ"] = decimal.Parse("0.000000");
                RestRow["FCURRENCYDEBITBQ"] = decimal.Parse("0.000000");
                RestRow["FCURRENCYCREDITBQ"] = decimal.Parse("0.000000");
                RestRow["FQUANTITYDEBITBQ"] = decimal.Parse("0.000000");
                RestRow["FQUANTITYCREDITBQ"] = decimal.Parse("0.000000");
                if (Range != "0")
                {
                    RestRow["FDEBITAMOUNTQC"] = NulltoDecimal(RestTB.Compute("sum(FDEBITAMOUNTQM)", string.Format("FACCCODE='{0}' and FRANGE={1}", SID, int.Parse(Range) - 1)).ToString());
                    RestRow["FCREDITAMOUNTQC"] = NulltoDecimal(RestTB.Compute("sum(FCREDITAMOUNTQM)", string.Format("FACCCODE='{0}' and FRANGE={1}", SID, int.Parse(Range) - 1)).ToString());
                    RestRow["FCURRENCYDEBITQC"] = NulltoDecimal(RestTB.Compute("sum(FCURRENCYDEBITQM)", string.Format("FACCCODE='{0}' and FRANGE={1}", SID, int.Parse(Range) - 1)).ToString());
                    RestRow["FCURRENCYCREDITQC"] = NulltoDecimal(RestTB.Compute("sum(FCURRENCYCREDITQM)", string.Format("FACCCODE='{0}' and FRANGE={1}", SID, int.Parse(Range) - 1)).ToString());
                    RestRow["FQUANTITYDEBITQC"] = NulltoDecimal(RestTB.Compute("sum(FQUANTITYDEBITQM)", string.Format("FACCCODE='{0}' and FRANGE={1}", SID, int.Parse(Range) - 1)).ToString());
                    RestRow["FQUANTITYCREDITQC"] = NulltoDecimal(RestTB.Compute("sum(FQUANTITYCREDITQM)", string.Format("FACCCODE='{0}' and FRANGE={1}", SID, int.Parse(Range) - 1)).ToString());
                }
                if (TempBillTB != null)
                {
                    RestRow["FDEBITAMOUNTBQ"] = NulltoDecimal(TempBillTB.Compute("sum(FDEBITAMOUNT)", string.Format("FACCOUNTCODE in ({0})", FCode)).ToString());
                    RestRow["FCREDITAMOUNTBQ"] = NulltoDecimal(TempBillTB.Compute("sum(FCREDITAMOUNT)", string.Format("FACCOUNTCODE in ({0})", FCode)).ToString());
                    RestRow["FCURRENCYDEBITBQ"] = NulltoDecimal(TempBillTB.Compute("sum(FCURRENCYDEBIT)", string.Format("FACCOUNTCODE in ({0})", FCode)).ToString());
                    RestRow["FCURRENCYCREDITBQ"] = NulltoDecimal(TempBillTB.Compute("sum(FCURRENCYCREDIT)", string.Format("FACCOUNTCODE in ({0})", FCode)).ToString());
                    RestRow["FQUANTITYDEBITBQ"] = NulltoDecimal(TempBillTB.Compute("sum(FQUANTITYDEBIT)", string.Format("FACCOUNTCODE in ({0})", FCode)).ToString());
                    RestRow["FQUANTITYCREDITBQ"] = NulltoDecimal(TempBillTB.Compute("sum(FQUANTITYCREDIT)", string.Format("FACCOUNTCODE in ({0})", FCode)).ToString());
                }
                RestRow["FDEBITAMOUNTQM"] = decimal.Parse(RestRow["FDEBITAMOUNTQC"].ToString()) + decimal.Parse(RestRow["FDEBITAMOUNTBQ"].ToString());
                RestRow["FCREDITAMOUNTQM"] = decimal.Parse(RestRow["FCREDITAMOUNTQC"].ToString()) + decimal.Parse(RestRow["FCREDITAMOUNTBQ"].ToString());
                RestRow["FCURRENCYDEBITQM"] = decimal.Parse(RestRow["FCURRENCYDEBITQC"].ToString()) + decimal.Parse(RestRow["FCURRENCYDEBITBQ"].ToString());
                RestRow["FCURRENCYCREDITQM"] = decimal.Parse(RestRow["FCURRENCYCREDITQC"].ToString()) + decimal.Parse(RestRow["FCURRENCYCREDITBQ"].ToString());
                RestRow["FQUANTITYDEBITQM"] = decimal.Parse(RestRow["FQUANTITYDEBITQC"].ToString()) + decimal.Parse(RestRow["FQUANTITYDEBITBQ"].ToString());
                RestRow["FQUANTITYCREDITQM"] = decimal.Parse(RestRow["FQUANTITYCREDITQC"].ToString()) + decimal.Parse(RestRow["FQUANTITYCREDITBQ"].ToString());
                RestRow["FRANGE"] = Range;
                RestRow["SINDEXDATE"] = System.DateTime.Now;
                RestRow["SBOOKID"] = "";
                RestTB.Rows.Add(RestRow);
            }
            return RestTB;
        }

        decimal NulltoDecimal(string Key)
        {
            if (StringUtils.IsEmpty(Key))
            {
                return decimal.Parse("0.000000");
            }
            return decimal.Parse(Key);
        }

        bool SyncBillNO(Hashtable args)
        {
            var param = AppSession.CreateServiceParamter(args);
            param["Action"] = "同步凭证号";
            var BillMasterTB = args["BillMasterTB"] as DataTable;
            param["BillMasterTB"] = Agile.Engine.Utils.ZipUtils.ZipDataTable(BillMasterTB);
            var exec = InvokeService(param);
            if (exec)
            {
                var NewBillMasterTB = Agile.Engine.Utils.ZipUtils.UnZipDataTable(ServiceProcess.Result["NewBillMasterTB"].ToString());
                DataAccess a = new DataAccess() { Context = DataContext, TableName = Master };
                a.Update(NewBillMasterTB.Select());
            }
            return exec;
        }

        #endregion

        #region //初始化

        public Hashtable InitializeBillCheck(Hashtable args)
        {
            var Sql = (string)null;
            Sql = string.Format("select * from TBILLMASTER where FSTATUS=4 and FENTERDATE<'{0}'", AppSession.Book["FBOOKSTARTIME"]);
            args["BillMasterTB"] = DataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, DataTableName, Sql);
            var filter0 = string.Format("and FSTATUS=4 and FENTERDATE<'{0}'", AppSession.Book["FBOOKSTARTIME"]);
            Sql = ObjectContext.GetResource("SqlResource").Format("billQuery", filter0,
                string.IsNullOrEmpty(null) ? string.Empty : ObjectContext.GetResource("SqlResource").Format("billSubQuery", null));
            args["BillDetailTB"] = DataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, DataTableName, Sql);
            args["AccountTB"] = DataContext.DefaultModel.QueryTable("TACCOUNT");
            var LowerAccountTB = CacheContext.LowerAccountCache();
            args["LowerAccountSID"] = string.Format("'{0}'", string.Join("','", (from a in LowerAccountTB.Select("") select a["SID"].ToString()).ToArray()));
            args["RestTB"] = DataContext.DefaultModel.QueryTable("TREST");
            return BillCheck(args);
        }

        Hashtable InitializeRestBuild(Hashtable args)
        {
            Hashtable mode = new Hashtable();
            int Year = DateTime.Parse(AppSession.Book["FBOOKSTARTIME"].ToString()).Year;
            var BillDetailTB = args["BillDetailTB"] as DataTable;
            var TempRestTB = args["RestTB"] as DataTable;
            var StarTime = DateTime.Parse(string.Format("{0}-{1}-1 00:00:00", Year, 1)).AddYears(-1);
            var EndTime = DateTime.Parse(string.Format("{0}-{1}-1 00:00:00", Year, 1));
            var TempBillDetailRow = (DataRow[])null;
            var IsBegin = 0;
            mode["Range"] = DateTime.Parse(AppSession.Book["FBOOKSTARTIME"].ToString()).Month;
            if (BillDetailTB.Rows.Count == 0)
            {
                mode["RestTB"] = TempRestTB;
                mode["State"] = 0;
                mode["Log"] += "----初始借方余额: 0.000000\r\n";
                mode["Log"] += "----初始借方余额: 0.000000\r\n";
                return mode;
            }
            for (int i = 0; i < int.Parse(mode["Range"].ToString()); i = i + 1)
            {
                args["Range"] = i;
                if (i != 0)
                {
                    StarTime = DateTime.Parse(string.Format("{0}-{1}-1 00:00:00", Year, i));
                    EndTime = StarTime.AddMonths(1);
                }
                TempBillDetailRow = BillDetailTB.Select(string.Format("FENTERDATE>= '{0}' and FENTERDATE<'{1}'", StarTime, EndTime));
                if (TempBillDetailRow.Length != 0)
                {
                    args["TempBillTB"] = TempBillDetailRow.CopyToDataTable();
                }
                else
                {
                    args["TempBillTB"] = (DataTable)null;
                }
                TempRestTB = RateBuild(args);
                args["RestTB"] = TempRestTB;
                if (IsBegin == 0)
                {
                    if (int.Parse(TempRestTB.Compute("count(FDEBITAMOUNTQM)", string.Format("FDEBITAMOUNTQM<>0.000000 and  FRANGE='{0}'", i)).ToString()) +
                            int.Parse(TempRestTB.Compute("count(FCREDITAMOUNTQM)", string.Format("FCREDITAMOUNTQM<>0.000000 and  FRANGE='{0}'", i)).ToString()) == 0)
                    {
                        TempRestTB.Rows.Clear();
                        args["RestTB"] = TempRestTB;
                    }
                    else
                    {
                        mode["Log"] += string.Format("----初始借方余额: {0}\r\n", NulltoDecimal(TempRestTB.Compute("sum(FDEBITAMOUNTQM)", string.Format("FRANGE='{0}' and FACCCODE in ({1})", i, args["LowerAccountSID"])).ToString()));
                        mode["Log"] += string.Format("----初始贷方余额: {0}\r\n", NulltoDecimal(TempRestTB.Compute("sum(FCREDITAMOUNTQM)", string.Format("FRANGE='{0}' and FACCCODE in ({1})", i, args["LowerAccountSID"])).ToString()));
                        IsBegin = IsBegin + 1;
                    }
                }
                else
                {
                    mode["Log"] += string.Format("----{0}月借方余额: {1}\r\n", i, NulltoDecimal(TempRestTB.Compute("sum(FDEBITAMOUNTQM)", string.Format("FRANGE='{0}' and FACCCODE in ({1})", i, args["LowerAccountSID"])).ToString()));
                    mode["Log"] += string.Format("----{0}月贷方余额: {1}\r\n", i, NulltoDecimal(TempRestTB.Compute("sum(FCREDITAMOUNTQM)", string.Format("FRANGE='{0}' and FACCCODE in ({1})", i, args["LowerAccountSID"])).ToString()));
                    IsBegin = IsBegin + 1;
                }
            }
            if (NulltoDecimal(TempRestTB.Compute("sum(FDEBITAMOUNTQM)", string.Format("FACCCODE in ({0})", args["LowerAccountSID"])).ToString()) !=
                   NulltoDecimal(TempRestTB.Compute("sum(FCREDITAMOUNTQM)", string.Format("FACCCODE in ({0})", args["LowerAccountSID"])).ToString()))
            {
                mode["State"] = 1;
            }
            else
            {
                mode["RestTB"] = args["RestTB"];
                mode["State"] = 0;
            }
            return mode;
        }

        bool InitializeSubmit(Hashtable args)
        {
            var param = AppSession.CreateServiceParamter(args);
            var RestTB = args["RestTB"] as DataTable;
            param["RestCount"] = RestTB.Rows.Count;
            if (int.Parse(param["RestCount"].ToString()) != 0)
            {
                param["RestTB"] = Agile.Engine.Utils.ZipUtils.ZipDataTable(RestTB);
            }
            var exec = InvokeService(param);
            if (exec)
            {
                DataContext.DefaultModel.Delete("TREST", "2=2");
                if (int.Parse(param["RestCount"].ToString()) != 0)
                {
                    RestTB = Agile.Engine.Utils.ZipUtils.UnZipDataTable(ServiceProcess.Result["RestTB"].ToString());
                    DataAccess a = new DataAccess() { Context = DataContext, TableName = "TREST" };
                    a.AddNew(RestTB.Select());
                }
                if (args["Range"].ToString().Equals("0"))
                    args["Range"] = "1";
                DataContext.DefaultModel.ExecuteNonQuery(string.Format("UPDATE TBOOK SET FBOOKINITIALIZED=1,FBOOKRANGE={0},SINDEXDATE='{1}'", args["Range"], ServiceProcess.Result["BOOKSINDEXDATE"]));
                AppSession.InitializeBookInfo();
            }
            return exec;
        }

        bool ReverseInitializeSubmit(Hashtable args)
        {
            var param = AppSession.CreateServiceParamter(args);
            var exec = InvokeService(param);
            if (exec)
            {
                DataContext.DefaultModel.Delete("TREST", "2=2");
                DataContext.DefaultModel.ExecuteNonQuery(string.Format("UPDATE TBOOK SET FBOOKINITIALIZED=0,FBOOKRANGE={0},SINDEXDATE='{1}'", args["InitializeRange"], ServiceProcess.Result["BOOKSINDEXDATE"]));
                AppSession.InitializeBookInfo();
            }
            return exec;
        }

        #endregion

        #region //结转损益

        Hashtable TransferProfit(Hashtable args)
        {
            Hashtable mode = new Hashtable();
            var Year = DateTime.Parse(AppSession.Book["FBOOKSTARTIME"].ToString()).Year;
            var Range = int.Parse(AppSession.Range);
            Range = (Range < 1) ? 1 : (Range > 12) ? 12 : Range;
            var StarTime = DateTime.Parse(string.Format("{0}-{1}-1 00:00:00", Year, Range));
            var EndTime = DateTime.Parse(string.Format("{0}-{1}-1 00:00:00", Year, Range)).AddMonths(1).AddMilliseconds(-1);
            var AccountTB = DataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, DataTableName,
                ObjectContext.GetResource("SqlResource").Format("TransferProfitAccount", string.Format("FENTERDATE>='{0}' and FENTERDATE<'{1}'", StarTime, EndTime)));
            var LowerAccountTB = CacheContext.LowerAccountCache();
            var filter0 = string.Format("and FENTERDATE>='{0}' and FENTERDATE<'{1}' and FSTATUS=2", StarTime, EndTime);
            //var filter0 = string.Format("and FENTERDATE>='{0}' and FENTERDATE<'{1}'", StarTime, EndTime);
            var Sql = ObjectContext.GetResource("SqlResource").Format("billQuery", filter0
                    , string.IsNullOrEmpty(null) ? string.Empty : ObjectContext.GetResource("SqlResource").Format("billSubQuery", null));
            var BillDetailTB = DataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, DataTableName, Sql);
            var AccountSID = string.Format("'{0}'", string.Join("','",
                  (from a in AccountTB.Select("") select a["SID"].ToString()).ToArray()));

            Sql = string.Format("select * from TBILLMASTER where FENTERDATE>='{0}' and FENTERDATE<'{1}'", StarTime, EndTime);
            var BillMasterTB = DataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, DataTableName, Sql);
            int NOCheckCount = int.Parse(BillMasterTB.Compute("count(SID)", "FSTATUS=0").ToString());
            int NOPostCount = int.Parse(BillMasterTB.Compute("count(SID)", "FSTATUS=1").ToString());
            if (NOCheckCount != 0)
            {
                mode["State"] = 1;
                mode["Message"] = string.Format("有{0}张凭证未审核，请审核后再进行结转！", NOCheckCount);
                return mode;
            }
            if (NOPostCount != 0)
            {
                mode["State"] = 1;
                mode["Message"] = string.Format("有{0}张凭证未过账，请过账后再进行结转！", NOPostCount);
                return mode;
            }
            if (LowerAccountTB.Compute("count(SID)", string.Format("SID='{0}'", args["FACCOUNTCODE"])).ToString() == "0")
            {
                mode["State"] = 1;
                mode["Message"] = "利润科目非最子级科目，请重新选择！";
                return mode;
            }
            var DetailRows = BillDetailTB.Select(string.Format("FACCOUNTCODE in ({0})", AccountSID));
            if (AccountTB.Rows.Count == 0 || DetailRows.Length == 0)
            {
                mode["State"] = 1;
                mode["Message"] = "本期没有损益类科目凭证，无需结转！";
                return mode;
            }
            BillDetailTB = DetailRows.CopyToDataTable();
            if (NulltoDecimal(BillDetailTB.Compute("sum(FDEBITAMOUNT)", "").ToString()) 
                        == NulltoDecimal(BillDetailTB.Compute("sum(FCREDITAMOUNT)", "").ToString()))
            {
                mode["State"] = 1;
                mode["Message"] = "本期损益类科目已经结转，无需重新结转！";
                return mode;
            }
            Hashtable Temp = new Hashtable();
            var TransferProfitDebit = DataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, DataTableName, "select * from TBILLDETAIL where 1=2");
            var TransferProfitCredit = DataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, DataTableName, "select * from TBILLDETAIL where 1=2");
            var TempRowDebit = (DataRow)null;
            var TempRowCredit = (DataRow)null;
            for (int i = 0; i < AccountTB.Rows.Count; i++)
            {
                if (AccountTB.Rows[i]["FJD"].ToString() == "1")
                {
                    TempRowDebit = TransferProfitDebit.NewRow();
                    TempRowDebit["FACCOUNTCODE"] = AccountTB.Rows[i]["SID"].ToString();
                    TempRowDebit["FEXPLANATION"] = args["FEXPLANATION"].ToString();
                    TempRowDebit["FCREDITAMOUNT"] =
                            NulltoDecimal(BillDetailTB.Compute("sum(FDEBITAMOUNT)",
                            string.Format("FACCOUNTCODE = '{0}'", TempRowDebit["FACCOUNTCODE"])).ToString()) -
                            NulltoDecimal(BillDetailTB.Compute("sum(FCREDITAMOUNT)",
                            string.Format("FACCOUNTCODE = '{0}'", TempRowDebit["FACCOUNTCODE"])).ToString());
                    if ((NulltoDecimal(TempRowDebit["FDEBITAMOUNT"].ToString()) + NulltoDecimal(TempRowDebit["FCREDITAMOUNT"].ToString())) != decimal.Parse("0.000000"))
                    {
                        TransferProfitDebit.Rows.Add(TempRowDebit);
                    }
                }
                else
                {
                    TempRowCredit = TransferProfitCredit.NewRow();
                    TempRowCredit["FACCOUNTCODE"] = AccountTB.Rows[i]["SID"].ToString();
                    TempRowCredit["FEXPLANATION"] = args["FEXPLANATION"].ToString();
                    TempRowCredit["FDEBITAMOUNT"] =
                            NulltoDecimal(BillDetailTB.Compute("sum(FCREDITAMOUNT)",
                            string.Format("FACCOUNTCODE = '{0}'", TempRowCredit["FACCOUNTCODE"])).ToString()) -
                            NulltoDecimal(BillDetailTB.Compute("sum(FDEBITAMOUNT)",
                            string.Format("FACCOUNTCODE = '{0}'", TempRowCredit["FACCOUNTCODE"])).ToString());
                    if ((NulltoDecimal(TempRowCredit["FDEBITAMOUNT"].ToString()) + NulltoDecimal(TempRowCredit["FCREDITAMOUNT"].ToString())) != decimal.Parse("0.000000"))
                    {
                        TransferProfitCredit.Rows.Add(TempRowCredit);
                    }
                }
            }
            if (TransferProfitDebit.Rows.Count != 0)
            {
                TempRowDebit = TransferProfitDebit.NewRow();
                TempRowDebit["FACCOUNTCODE"] = args["FACCOUNTCODE"].ToString();
                TempRowDebit["FEXPLANATION"] = args["FEXPLANATION"].ToString();
                TempRowDebit["FDEBITAMOUNT"] = NulltoDecimal(TransferProfitDebit.Compute("sum(FCREDITAMOUNT)", "").ToString());
                TransferProfitDebit.Rows.Add(TempRowDebit);
            }
            if (TransferProfitCredit.Rows.Count != 0)
            {
                TempRowCredit = TransferProfitCredit.NewRow();
                TempRowCredit["FACCOUNTCODE"] = args["FACCOUNTCODE"].ToString();
                TempRowCredit["FEXPLANATION"] = args["FEXPLANATION"].ToString();
                TempRowCredit["FCREDITAMOUNT"] = NulltoDecimal(TransferProfitCredit.Compute("sum(FDEBITAMOUNT)", "").ToString());
                TransferProfitCredit.Rows.Add(TempRowCredit);
            }
            args["Action"] = "结转损益提交";
            args["TransferProfitDebit"] = TransferProfitDebit;
            args["TransferProfitCredit"] = TransferProfitCredit;
            if (ExecuteUpdate(args))
            {
                mode["State"] = 0;
                mode["Message"] = "结转损益成功！";
            }
            else
            {
                mode["State"] = 1;
                mode["Message"] = "结转损益失败，请稍候重试！";
            }
            return mode;
        }

        bool TransferProfitSubmit(Hashtable args)
        {
            var param = AppSession.CreateServiceParamter(args);
            param["Action"] = "结转损益提交";
            param["UserSID"] = AppSession.UserSID;
            param["BillType"] = AppSession.Book["FBILLTYPE"];
            param["Year"] = DateTime.Parse(AppSession.Book["FBOOKSTARTIME"].ToString()).Year;
            param["Range"] = int.Parse(AppSession.Range);
            var TransferProfitDebit = args["TransferProfitDebit"] as DataTable;
            param["TransferProfitDebitCount"] = TransferProfitDebit.Rows.Count;
            if (int.Parse(param["TransferProfitDebitCount"].ToString()) != 0)
            {
                param["TransferProfitDebit"] = Agile.Engine.Utils.ZipUtils.ZipDataTable(TransferProfitDebit);
            }
            var TransferProfitCredit = args["TransferProfitCredit"] as DataTable;
            param["TransferProfitCreditCount"] = TransferProfitCredit.Rows.Count;
            if (int.Parse(param["TransferProfitCreditCount"].ToString()) != 0)
            {
                param["TransferProfitCredit"] = Agile.Engine.Utils.ZipUtils.ZipDataTable(TransferProfitCredit);
            }
            var exec = InvokeService(param);
            if (exec)
            {
                var BillMasterTB = Agile.Engine.Utils.ZipUtils.UnZipDataTable(ServiceProcess.Result["BillMasterTB"].ToString());
                var BillDetailTB = Agile.Engine.Utils.ZipUtils.UnZipDataTable(ServiceProcess.Result["BillDetailTB"].ToString());
                DataAccess a = new DataAccess() { Context = DataContext, TableName = Master };
                a.AddNew(BillMasterTB.Select());
                DataAccess b = new DataAccess() { Context = DataContext, TableName = Detail };
                b.AddNew(BillDetailTB.Select());
            }
            return exec;
        }

        #endregion

        #region //期末调汇

        Hashtable AdjustRate(Hashtable args)
        {
            Hashtable mode = new Hashtable();
            var Sql = (string)null;
            var Year = DateTime.Parse(AppSession.Book["FBOOKSTARTIME"].ToString()).Year;
            var Range = int.Parse(AppSession.Range);
            Range = (Range < 1) ? 1 : (Range > 12) ? 12 : Range;
            var StarTime = DateTime.Parse(string.Format("{0}-{1}-1 00:00:00", Year, Range));
            var EndTime = DateTime.Parse(string.Format("{0}-{1}-1 00:00:00", Year, Range)).AddMonths(1).AddMilliseconds(-1);
            var AccountTB = DataContext.DefaultModel.QueryTable("TACCOUNT");
            var LowerAccountTB = CacheContext.LowerAccountCache();
            var filter0 = string.Format("and FENTERDATE>='{0}' and FENTERDATE<'{1}' and FSTATUS=2", StarTime, EndTime);
            //var filter0 = string.Format("and FENTERDATE>='{0}' and FENTERDATE<'{1}'", StarTime, EndTime);
            Sql = ObjectContext.GetResource("SqlResource").Format("billQuery", filter0
                    , string.IsNullOrEmpty(null) ? string.Empty : ObjectContext.GetResource("SqlResource").Format("billSubQuery", null));
            var BillDetailTB = DataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, DataTableName, Sql);
            Sql = "select a.SID,b.FNAME,b.FRATE from TACCOUNT as a,TRATE as b where a.FBZ=b.SID and a.FBZ <> 'defaultCurrencyRate'";
            var RateTB = DataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, DataTableName, Sql);

            Sql = string.Format("select * from TBILLMASTER where FENTERDATE>='{0}' and FENTERDATE<'{1}'", StarTime, EndTime);
            var BillMasterTB = DataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, DataTableName, Sql);
            int NOCheckCount = int.Parse(BillMasterTB.Compute("count(SID)", "FSTATUS=0").ToString());
            int NOPostCount = int.Parse(BillMasterTB.Compute("count(SID)", "FSTATUS=1").ToString());
            if (NOCheckCount != 0)
            {
                mode["State"] = 1;
                mode["Message"] = string.Format("有{0}张凭证未审核，请审核后再进行结转！", NOCheckCount);
                return mode;
            }
            if (NOPostCount != 0)
            {
                mode["State"] = 1;
                mode["Message"] = string.Format("有{0}张凭证未过账，请过账后再进行结转！", NOPostCount);
                return mode;
            }
            if (LowerAccountTB.Compute("count(SID)", string.Format("SID='{0}'", args["FACCOUNTCODE"])).ToString() == "0")
            {
                mode["State"] = 1;
                mode["Message"] = "损益科目非最子级科目，请重新选择！";
                return mode;
            }
            if (LowerAccountTB.Compute("count(SID)", "FBZ<>'defaultCurrencyRate'").ToString() == "0")
            {
                mode["State"] = 1;
                mode["Message"] = "没有外币科目,无需调汇！";
                return mode;
            }
            var LowerAccountSID = string.Format("'{0}'", string.Join("','",
                (from a in LowerAccountTB.Select("FBZ<>'defaultCurrencyRate'") select a["SID"].ToString()).ToArray()));
            args["Year"] = Year;
            args["Range"] = Range;
            args["TempBillTB"] = BillDetailTB;
            args["AccountTB"] = AccountTB;
            args["RestTB"] = DataContext.DefaultModel.QueryTable("TREST");
            var RestTB = RateBuild(args).Select(string.Format("FRANGE= '{0}' and FACCCODE in ({1})", Range, LowerAccountSID)).CopyToDataTable();
            Hashtable Temp = new Hashtable();
            var AdjustRateDetailTB = DataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, DataTableName, "select * from TBILLDETAIL where 1=2");
            var TempBillRow = (DataRow)null;
            var FDEBITAMOUNTQM = decimal.Parse("0.000000");
            var FCREDITAMOUNTQM = decimal.Parse("0.000000");
            var FCURRENCYDEBITQM = decimal.Parse("0.000000");
            var FCURRENCYCREDITQM = decimal.Parse("0.000000");
            var NewAmount = decimal.Parse("0.000000");
            var NewRate = decimal.Parse("0.000000");
            var FJD = 0;
            var FBZ = (string)null;
            for (int i = 0; i < RestTB.Rows.Count; i++)
            {
                TempBillRow = AdjustRateDetailTB.NewRow();
                FDEBITAMOUNTQM = NulltoDecimal(RestTB.Rows[i]["FDEBITAMOUNTQM"].ToString());
                FCREDITAMOUNTQM = NulltoDecimal(RestTB.Rows[i]["FCREDITAMOUNTQM"].ToString());
                FCURRENCYDEBITQM = NulltoDecimal(RestTB.Rows[i]["FCURRENCYDEBITQM"].ToString());
                FCURRENCYCREDITQM = NulltoDecimal(RestTB.Rows[i]["FCURRENCYCREDITQM"].ToString());

                TempBillRow["FACCOUNTCODE"] = RestTB.Rows[i]["FACCCODE"].ToString();
                FJD = int.Parse(LowerAccountTB.Select(string.Format("SID='{0}'", TempBillRow["FACCOUNTCODE"])).CopyToDataTable().Rows[0]["FJD"].ToString());
                FBZ = RateTB.Select(string.Format("SID='{0}'", TempBillRow["FACCOUNTCODE"])).CopyToDataTable().Rows[0]["FNAME"].ToString();
                NewRate = NulltoDecimal(RateTB.Select(string.Format("SID='{0}'", TempBillRow["FACCOUNTCODE"])).CopyToDataTable().Rows[0]["FRATE"].ToString());
                if (FCURRENCYDEBITQM != FCURRENCYCREDITQM)
                {
                    if ((FCURRENCYDEBITQM - FCURRENCYCREDITQM) * NewRate - (FDEBITAMOUNTQM - FCREDITAMOUNTQM) != decimal.Parse("0.000000"))
                    {
                        if (FJD == 1)
                        {
                            NewAmount = (FCURRENCYDEBITQM - FCURRENCYCREDITQM) * NewRate - (FDEBITAMOUNTQM - FCREDITAMOUNTQM);
                            if (NewAmount > decimal.Parse("0.000000"))
                            {
                                TempBillRow["FDEBITAMOUNT"] = NewAmount;
                            }
                            else
                            {
                                TempBillRow["FCREDITAMOUNT"] = NewAmount;
                            }
                        }
                        else
                        {
                            NewAmount = (FCURRENCYCREDITQM - FCURRENCYDEBITQM) * NewRate - (FCREDITAMOUNTQM - FDEBITAMOUNTQM);
                            if (NewAmount > decimal.Parse("0.000000"))
                            {
                                TempBillRow["FCREDITAMOUNT"] = NewAmount;
                            }
                            else
                            {
                                TempBillRow["FDEBITAMOUNT"] = NewAmount;
                            }
                        }
                        TempBillRow["FEXPLANATION"] = string.Format("{0}调汇", FBZ);
                        TempBillRow["FRATE"] = NewRate;
                        AdjustRateDetailTB.Rows.Add(TempBillRow);
                    }
                }
            }
            if (AdjustRateDetailTB.Rows.Count != 0)
            {
                TempBillRow = AdjustRateDetailTB.NewRow();
                TempBillRow["FACCOUNTCODE"] = args["FACCOUNTCODE"].ToString();
                TempBillRow["FEXPLANATION"] = "结转汇兑损益";
                NewAmount = NulltoDecimal(AdjustRateDetailTB.Compute("sum(FDEBITAMOUNT)", "").ToString()) -
                                NulltoDecimal(AdjustRateDetailTB.Compute("sum(FCREDITAMOUNT)", "").ToString());
                if (NewAmount > decimal.Parse("0.000000"))
                {
                    TempBillRow["FCREDITAMOUNT"] = NewAmount;
                    AdjustRateDetailTB.Rows.Add(TempBillRow);
                }
                if (NewAmount < decimal.Parse("0.000000"))
                {
                    TempBillRow["FDEBITAMOUNT"] = NewAmount;
                    AdjustRateDetailTB.Rows.Add(TempBillRow);
                }
                args["Action"] = "期末调汇提交";
                args["AdjustRateDetailTB"] = AdjustRateDetailTB;
                if (ExecuteUpdate(args))
                {
                    mode["State"] = 0;
                    mode["Message"] = "期末调汇成功！";
                }
                else
                {
                    mode["State"] = 1;
                    mode["Message"] = "期末调汇失败，请稍候重试！";
                } 
            }
            else
            {
                mode["State"] = 1;
                mode["Message"] = "没有外币金额发生,无需调汇！";
            }
            return mode;
            
        }

        bool AdjustRateSubmit(Hashtable args)
        {
            var param = AppSession.CreateServiceParamter(args);
            param["Action"] = "期末调汇提交";
            param["UserSID"] = AppSession.UserSID;
            param["BillType"] = AppSession.Book["FBILLTYPE"];
            var AdjustRateDetailTB = args["AdjustRateDetailTB"] as DataTable;
            param["AdjustRateDetailCount"] = AdjustRateDetailTB.Rows.Count;
            if (int.Parse(param["AdjustRateDetailCount"].ToString()) != 0)
            {
                param["AdjustRateDetailTB"] = Agile.Engine.Utils.ZipUtils.ZipDataTable(AdjustRateDetailTB);
            }
            var exec = InvokeService(param);
            if (exec)
            {
                var BillMasterTB = Agile.Engine.Utils.ZipUtils.UnZipDataTable(ServiceProcess.Result["BillMasterTB"].ToString());
                var BillDetailTB = Agile.Engine.Utils.ZipUtils.UnZipDataTable(ServiceProcess.Result["BillDetailTB"].ToString());
                DataAccess a = new DataAccess() { Context = DataContext, TableName = Master };
                a.AddNew(BillMasterTB.Select());
                DataAccess b = new DataAccess() { Context = DataContext, TableName = Detail };
                b.AddNew(BillDetailTB.Select());
            }
            return exec;
        }

        #endregion

        #region //凭证审核

        public Hashtable CertificateAuditBillCheck(Hashtable args)
        {
            return BillCheck(args);
        }

        bool CertificateAuditSubmit(Hashtable args)
        {
            var param = AppSession.CreateServiceParamter(args);
            var BillMasterTB = args["BillMasterTB"] as DataTable;
            param["FCHECKED"] = AppSession.UserSID;
            param["BillMasterSID"] = string.Format("'{0}'", string.Join("','",
                (from a in BillMasterTB.Select(string.Format("FSTATUS=0 and (FENTER<>'{0}' or FENTER is null)", param["FCHECKED"])) select a["SID"].ToString()).ToArray()));
            param["Action"] = "凭证审核提交";
            var exec = InvokeService(param);
            if (exec)
            {
                var NewBillMasterTB = Agile.Engine.Utils.ZipUtils.UnZipDataTable(ServiceProcess.Result["NewBillMasterTB"].ToString());
                DataAccess a = new DataAccess() { Context = DataContext, TableName = Master };
                a.Update(NewBillMasterTB.Select());
            }
            return exec;
        }

        bool ReverseCertificateAuditSubmit(Hashtable args)
        {
            var param = AppSession.CreateServiceParamter(args);
            var BillMasterTB = args["BillMasterTB"] as DataTable;
            param["FCHECKED"] = AppSession.UserSID;
            param["BillMasterSID"] = string.Format("'{0}'", string.Join("','",
                (from a in BillMasterTB.Select(string.Format("FSTATUS=1 and FCHECKED='{0}'", param["FCHECKED"])) select a["SID"].ToString()).ToArray()));
            param["Action"] = "凭证反审核提交";
            var exec = InvokeService(param);
            if (exec)
            {
                var NewBillMasterTB = Agile.Engine.Utils.ZipUtils.UnZipDataTable(ServiceProcess.Result["NewBillMasterTB"].ToString());
                DataAccess a = new DataAccess() { Context = DataContext, TableName = Master };
                a.Update(NewBillMasterTB.Select());
            }
            return exec;
        }

        #endregion

        #region //凭证过账

        Hashtable CertificatePosting(Hashtable args)
        {
            var Year = DateTime.Parse(AppSession.Book["FBOOKSTARTIME"].ToString()).Year;
            var Range = int.Parse(AppSession.Range);
            Range = (Range < 1) ? 1 : (Range > 12) ? 12 : Range;
            var Sql = string.Format("select * from TBILLMASTER where FENTERDATE>='{0}' and FENTERDATE<'{1}'",
                    DateTime.Parse(string.Format("{0}-{1}-1 00:00:00", Year, Range)),
                    DateTime.Parse(string.Format("{0}-{1}-1 00:00:00", Year, Range)).AddMonths(1).AddMilliseconds(-1));
            var BillMasterTB = DataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, DataTableName, Sql);
            Hashtable mode = new Hashtable();
            int NOCheckCount = int.Parse(BillMasterTB.Compute("count(SID)", "FSTATUS=0").ToString());
            int NOPostCount = int.Parse(BillMasterTB.Compute("count(SID)", "FSTATUS=1").ToString());
            if (NOPostCount == 0)
            {
                mode["State"] = 1;
                mode["Message"] = "没有需要过账的凭证！";
            }
            else
            {
                args["Action"] = "凭证过账提交";
                args["BillMasterSID"] = string.Format("'{0}'", string.Join("','",
                    (from a in BillMasterTB.Select("FSTATUS=1") select a["SID"].ToString()).ToArray()));
                if (ExecuteUpdate(args))
                {
                    mode["State"] = 0;
                    mode["Message"] = string.Format("凭证过账完成,过账凭证数:{0},未审核凭证数:{1}！", NOPostCount, NOCheckCount);
                }
                else
                {
                    mode["State"] = 1;
                    mode["Message"] = "凭证过账失败,请稍候重试！";
                }
            }
            return mode;
        }

        bool CertificatePostingSubmit(Hashtable args)
        {
            var param = AppSession.CreateServiceParamter(args);
            param["Action"] = "凭证过账提交";
            param["FPOST"] = AppSession.UserSID;
            var exec = InvokeService(param);
            if (exec)
            {
                var NewBillMasterTB = Agile.Engine.Utils.ZipUtils.UnZipDataTable(ServiceProcess.Result["NewBillMasterTB"].ToString());
                DataAccess a = new DataAccess() { Context = DataContext, TableName = Master };
                a.Update(NewBillMasterTB.Select());
            }
            return exec;
        }

        Hashtable ReverseCertificatePosting(Hashtable args)
        {
            var Year = DateTime.Parse(AppSession.Book["FBOOKSTARTIME"].ToString()).Year;
            var Range = int.Parse(AppSession.Range);
            Range = (Range < 1) ? 1 : (Range > 12) ? 12 : Range;
            var Sql = string.Format("select * from TBILLMASTER where FENTERDATE>='{0}' and FENTERDATE<'{1}'",
                    DateTime.Parse(string.Format("{0}-{1}-1 00:00:00", Year, Range)),
                    DateTime.Parse(string.Format("{0}-{1}-1 00:00:00", Year, Range)).AddMonths(1).AddMilliseconds(-1));
            var BillMasterTB = DataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, DataTableName, Sql);
            Hashtable mode = new Hashtable();
            int PostCount = int.Parse(BillMasterTB.Compute("count(SID)", "FSTATUS=2").ToString());
            if (PostCount == 0)
            {
                mode["State"] = 1;
                mode["Message"] = "没有需要反过账的凭证！";
            }
            else
            {
                args["Action"] = "凭证反过账提交";
                args["BillMasterSID"] = string.Format("'{0}'", string.Join("','",
                    (from a in BillMasterTB.Select("FSTATUS=2") select a["SID"].ToString()).ToArray()));
                if (ExecuteUpdate(args))
                {
                    mode["State"] = 0;
                    mode["Message"] = string.Format("凭证反过账完成,反过账凭证数:{0}！", PostCount);
                }
                else
                {
                    mode["State"] = 1;
                    mode["Message"] = "凭证反过账失败,请稍候重试！";
                }
            }
            return mode;
        }

        bool ReverseCertificatePostingSubmit(Hashtable args)
        {
            var param = AppSession.CreateServiceParamter(args);
            param["Action"] = "凭证反过账提交";
            var exec = InvokeService(param);
            if (exec)
            {
                var NewBillMasterTB = Agile.Engine.Utils.ZipUtils.UnZipDataTable(ServiceProcess.Result["NewBillMasterTB"].ToString());
                DataAccess a = new DataAccess() { Context = DataContext, TableName = Master };
                a.Update(NewBillMasterTB.Select());
            }
            return exec;
        }

        #endregion

        #region //结账

        Hashtable AccountSettleCheck(Hashtable args)
        {
            var Sql = (string)null;
            var Year = int.Parse(args["Year"].ToString());
            var Range = int.Parse(args["Range"].ToString());
            var StarTime = DateTime.Parse(string.Format("{0}-{1}-1 00:00:00", Year, Range));
            var EndTime = DateTime.Parse(string.Format("{0}-{1}-1 00:00:00", Year, Range)).AddMonths(1);
            Sql = string.Format("select * from TBILLMASTER where FENTERDATE>='{0}' and FENTERDATE<'{1}'", StarTime, EndTime);
            args["BillMasterTB"] = DataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, DataTableName, Sql);
            var filter0 = string.Format("and FENTERDATE>='{0}' and FENTERDATE<'{1}' and FSTATUS=2", StarTime, EndTime);
            Sql = ObjectContext.GetResource("SqlResource").Format("billQuery", filter0
                    , string.IsNullOrEmpty(null) ? string.Empty : ObjectContext.GetResource("SqlResource").Format("billSubQuery", null));
            args["BillDetailTB"] = DataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, DataTableName, Sql);
            args["AccountTB"] = DataContext.DefaultModel.QueryTable("TACCOUNT");
            var LowerAccountTB = CacheContext.LowerAccountCache();
            args["LowerAccountSID"] = string.Format("'{0}'", string.Join("','", (from a in LowerAccountTB.Select("") select a["SID"].ToString()).ToArray()));
            Sql = ObjectContext.GetResource("SqlResource").Format("TransferProfitAccount", string.Format("FENTERDATE>='{0}' and FENTERDATE<'{1}'", StarTime, EndTime));
            var TransferProfitAccountTB = DataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, DataTableName, Sql);
            args["TransferProfitAccountSID"] = string.Format("'{0}'", string.Join("','", (from a in TransferProfitAccountTB.Select("") select a["SID"].ToString()).ToArray()));
            Sql = string.Format("select * from TREST where FRANGE={0}", Range - 1);
            args["RestTB"] = DataContext.DefaultModel.QueryTable(System.Data.CommandType.Text, DataTableName, Sql);

            System.Collections.Hashtable mode = new System.Collections.Hashtable();
            var BillMasterTB = args["BillMasterTB"] as DataTable;
            var BillDetailTB = args["BillDetailTB"] as DataTable;
            var TransferProfitAccountSID = args["TransferProfitAccountSID"].ToString();
            int NOCheckCount = int.Parse(BillMasterTB.Compute("count(SID)", "FSTATUS=0").ToString());
            int NOPostCount = int.Parse(BillMasterTB.Compute("count(SID)", "FSTATUS=1").ToString());
            if (NOCheckCount != 0)
            {
                mode["State"] = 1;
                mode["Message"] = string.Format("有{0}张凭证未审核，请审核后再进行结账！", NOCheckCount);
                return mode;
            }
            if (NOPostCount != 0)
            {
                mode["State"] = 1;
                mode["Message"] = string.Format("有{0}张凭证未过账，请过账后再进行结账！", NOPostCount);
                return mode;
            }
            if (NulltoDecimal(BillDetailTB.Compute("sum(FDEBITAMOUNT)", string.Format("FACCOUNTCODE in ({0}) and FSTATUS=2", TransferProfitAccountSID)).ToString()) !=
                NulltoDecimal(BillDetailTB.Compute("sum(FCREDITAMOUNT)", string.Format("FACCOUNTCODE in ({0}) and FSTATUS=2", TransferProfitAccountSID)).ToString()))
            {
                mode["State"] = 1;
                mode["Message"] = "存在损益类科目未结转，请先进行结转！";
                return mode;
            }
            for (int i = 0; i < BillMasterTB.Rows.Count; i++)
            {
                if (int.Parse(BillMasterTB.Rows[i]["FNO"].ToString()) != i + 1)
                {
                    mode["State"] = -2;
                    mode["Message"] = "凭证号未连续，是否重新生成凭证号！";
                    return mode;
                }
            }
                mode["State"] = 0;
            return mode;
        }

        Hashtable AccountSettleRestBuild(Hashtable args)
        {
            Hashtable mode = new Hashtable();
            args["TempBillTB"] = args["BillDetailTB"] as DataTable;
            var ResltTB = RateBuild(args).Select(string.Format("FRANGE= '{0}'", args["Range"])).CopyToDataTable();
            if (NulltoDecimal(ResltTB.Compute("sum(FDEBITAMOUNTQM)", string.Format("FACCCODE in ({0})", args["LowerAccountSID"])).ToString()) !=
                  NulltoDecimal(ResltTB.Compute("sum(FCREDITAMOUNTQM)", string.Format("FACCCODE in ({0})", args["LowerAccountSID"])).ToString()))
            {
                mode["State"] = 1;
                mode["Message"] = "科目余额借贷不平，请调整后重新结账！";
                mode["RestTB"] = ResltTB;
            }
            else
            {
                mode["RestTB"] = ResltTB;
                mode["Range"] = args["Range"];
                mode["State"] = 0;
            }
            return mode;
        }

        bool AccountSettleSubmit(Hashtable args)
        {
            var param = AppSession.CreateServiceParamter(args);
            var RestTB = args["RestTB"] as DataTable;
            param["RestTB"] = Agile.Engine.Utils.ZipUtils.ZipDataTable(RestTB);
            param["Action"] = "结账信息提交";
            var exec = InvokeService(param);
            if (exec)
            {
                DataContext.DefaultModel.Delete("TREST", string.Format("2=2 and FRANGE='{0}'", args["Range"].ToString()));
                RestTB = Agile.Engine.Utils.ZipUtils.UnZipDataTable(ServiceProcess.Result["RestTB"].ToString());
                DataAccess a = new DataAccess() { Context = DataContext, TableName = "TREST" };
                a.AddNew(RestTB.Select());
                DataContext.DefaultModel.ExecuteNonQuery(string.Format("UPDATE TBOOK SET FBOOKINITIALIZED=1,FBOOKRANGE={0},SINDEXDATE='{1}'", int.Parse(args["Range"].ToString()) + 1, ServiceProcess.Result["BOOKSINDEXDATE"]));
                AppSession.InitializeBookInfo();
            }
            return exec;
        }

        bool ReverseAccountSettleSubmit(Hashtable args)
        {
            var param = AppSession.CreateServiceParamter(args);
            param["Action"] = "反结账信息提交";
            var exec = InvokeService(param);
            if (exec)
            {
                DataContext.DefaultModel.Delete("TREST", string.Format("2=2 and FRANGE='{0}'", int.Parse(args["Range"].ToString()) - 1));
                DataContext.DefaultModel.ExecuteNonQuery(string.Format("UPDATE TBOOK SET FBOOKINITIALIZED=1,FBOOKRANGE={0},SINDEXDATE='{1}'", int.Parse(args["Range"].ToString()) - 1, ServiceProcess.Result["BOOKSINDEXDATE"]));
                AppSession.InitializeBookInfo();
            }
            return exec;
        }

        #endregion








    }
}
